#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <cmath>

using namespace std;

constexpr int N = 1e3 + 5;

double dp[N][N];

double q[N][N];
int n, m;


int main() {

    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> q[i][j];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
            dp[i][j] = max(dp[i][j], dp[i-1][j-1] + q[i][j]);
        }
    }

    int cur_i = n, cur_j = m;
    vector<pair<int, int>> ans;
    while (cur_i != 0 && cur_j != 0) {
        if (dp[cur_i][cur_j] > dp[cur_i-1][cur_j] && dp[cur_i][cur_j] > dp[cur_i][cur_j-1]) {
            ans.push_back({cur_i, cur_j});
            cur_i --;
            cur_j --;
        } else {
            if (dp[cur_i][cur_j] == dp[cur_i-1][cur_j]) {
                cur_i --;
            } else {
                cur_j --;
            }
        }
    }
    reverse(ans.begin(), ans.end());
    cout << dp[n][m] << endl;
    for (auto x : ans) {
        cout << x.first << ' ' << x.second << endl;
    }
    unordered_set<int> axis_x, axis_y;
    double ans_check = q[ans[0].first][ans[0].second];
    for (int i = 1; i < ans.size(); ++i) {
        ans_check += q[ans[i].first][ans[i].second];
        if (ans[i].first <=  ans[i-1].first || ans[i].second <= ans[i-1].second) {
            std::cout << "error" << endl;
        }
    }

    if (fabs(ans_check - dp[n][m]) > 1e-6) {
        cout << ans_check << ' ' << dp[n][m] << endl;
        std::cout << "error2 " << endl;
    }

    return 0;
}
